class StyleEvent extends Event {
    style;
    value;
    constructor(type = 'stylechange', option) {
        super(type, option);
        this.style = option.style;
        this.value = option.value;
    }
}
/**可省略单位属性 */
const STYLEDEGREE = new Set([
    'width',
    'maxWidth',
    'minWidth',
    'height',
    'maxHeight',
    'minHeight',
    'left',
    'right',
    'top',
    'bottom',
    'padding',
    'margin',
    'fontSize',
    'lineHeight',
]);
/**FormJson默认选项 */
const defaultFormJsonOption = {
    input: 'input[name]:enabled,select[name]:enabled,textarea[name]:enabled',
    defaultValue: {}
};
export class FlyselError extends Error {
}
/**form表单收集 */
export class FormJson {
    #form;
    #option;
    constructor(form, option = {}) {
        const op = Object.assign({}, defaultFormJsonOption, option);
        this.#form = form;
        this.#option = op;
        this.collect();
    }
    set(name, value, element) {
        if (element?.hasAttribute('number'))
            value = +value;
        this[name] = value;
    }
    add(name, item) {
        const set = this[name];
        if (set instanceof Set) {
            set.add(item);
        }
        else {
            this[name] = new Set([item]);
        }
    }
    collect() {
        if (this.#option.defaultValue)
            Object.assign(this, this.#option.defaultValue);
        if (this.#form) {
            const fs = this.#form.find(this.#option.input);
            for (let i = 0; i < fs.length; i++) {
                const e = fs[i];
                const { name, value, type } = e;
                if (type === 'radio') {
                    if (e.checked) {
                        this.set(name, value);
                    }
                }
                else if (type === 'checkbox') {
                    if (e.checked) {
                        this.add(name, value);
                    }
                }
                else {
                    this.set(name, value);
                }
            }
        }
    }
    getOption() {
        return this.#option;
    }
}
/**Flysel事件系统 */
export class FlyselEvent {
    #listenerMap = new Map;
    onaddlistener = null;
    onremovelistener = null;
    onemitevent = null;
    /**
     * 侦听事件
     * @param type 事件类型
     * @param listener 事件侦听器
     * @param option 事件选项
     * @returns
     */
    on(type, listener, option) {
        let ls = this.#listenerMap.get(type);
        if (!ls) {
            ls = new Set;
            this.#listenerMap.set(type, ls);
        }
        //@ts-ignore
        this.onaddlistener && this.onaddlistener({ type, listener });
        ls.add(listener);
        if (option?.once) {
            const x = () => {
                ls?.delete(listener);
                ls?.delete(x);
            };
        }
        return true;
    }
    /**
     * 取消事件侦听器
     * @param type 事件类型
     * @param listener 事件侦听器
     * @param option 事件选项
     * @returns
     */
    off(type, listener) {
        const set = this.#listenerMap.get(type);
        if (set) {
            const hasDelete = set.delete(listener);
            // @ts-ignore
            this.onremovelistener && this.onremovelistener({ type, listener, hasDelete });
            return hasDelete;
        }
        return false;
    }
    /**
     * 发生事件
     * @param type 事件类型
     * @param event 事件参数
     * @returns
     */
    emit(type, event) {
        const set = this.#listenerMap.get(type);
        if (set) {
            set.forEach(ls => {
                ls.call(this, event);
            });
            //@ts-ignore
            this.onemitevent && this.onemitevent({ type, length: set.size });
            return true;
        }
        return false;
    }
}
/**内置事件（钩子函数） */
export const hook = new FlyselEvent();
/**
 * Flying Select 类
 */
export class Flysel {
    splice() { }
    /**长度 */
    length = 0;
    constructor(element) {
        if (element)
            this.add(element);
        Object.defineProperty(this, 'length', {
            enumerable: false,
            value: element ? 1 : 0
        });
        hook.emit('instantiation', { flysel: this, element });
    }
    /**返回第一个原生E对象 */
    get e() {
        return this[0];
    }
    /**
     * 获取指定索引的Flysel对象
     * @param {number} index 索引
     * @returns {Flysel}
     */
    get(index) {
        const e = this[index];
        return new Flysel(e);
    }
    /**
     * 添加元素
     * @param element
     * @returns
     */
    add(element) {
        return this[this.length] = element, this.length++, this;
    }
    /**
     * 过滤元素
     * @param {ergodicCallBlck} callBlck 回调函数
     */
    filter(callBlck) {
        // @ts-ignore
        if (callBlck[Symbol.toStringTag] === 'AsyncFunction') {
            return (async () => {
                const flysel = new Flysel;
                for (let index = 0; index < this.length; index++) {
                    const element = this[index];
                    if (await callBlck(new Flysel(element), index, this))
                        flysel.add(element);
                }
                console.log('n');
                return flysel;
            })();
        }
        else {
            const flysel = new Flysel;
            for (let index = 0; index < this.length; index++) {
                const element = this[index];
                if (callBlck(new Flysel(element), index, this))
                    flysel.add(element);
            }
            return flysel;
        }
    }
    /**筛选 */
    screen(selector) {
        const fs = new Flysel;
        for (let i = 0; i < this.length; i++) {
            const e = this[i];
            if (e.matches(selector))
                fs.add(e);
        }
        return fs;
    }
    /**
     * 遍历元素
     * @param {ergodicCallBlck} callBlck 回调函数
     */
    forEach(callBlck) {
        // @ts-ignore
        if (callBlck[Symbol.toStringTag] === 'AsyncFunction') {
            return (async () => {
                for (let index = 0; index < this.length; index++) {
                    const element = this[index];
                    await callBlck(new Flysel(element), index, this);
                }
            })();
        }
        else {
            for (let index = 0; index < this.length; index++) {
                const element = this[index];
                callBlck(new Flysel(element), index, this);
            }
        }
    }
    /**
     * 遍历元素并返回一个新数组
     * @param {ergodicCallBlck} callBlck 回调函数
     */
    map(callBlck) {
        // @ts-ignore
        if (callBlck[Symbol.toStringTag] === 'AsyncFunction') {
            return (async () => {
                const array = [];
                for (let index = 0; index < this.length; index++) {
                    const element = this[index];
                    array.push(await callBlck(new Flysel(element), index, this));
                }
                return array;
            })();
        }
        else {
            const array = [];
            for (let index = 0; index < this.length; index++) {
                const element = this[index];
                array.push(callBlck(new Flysel(element), index, this));
            }
            return array;
        }
    }
    /**
     * 返回是否存在指定element
     * @param element
     * @returns
     */
    includes(element) {
        if (element instanceof Flysel)
            element = element[0];
        for (let i = 0; i < this.length; i++) {
            if (element.isEqualNode(this[i]))
                return true;
        }
        return false;
    }
    /**
     * 转为字符串
     * @param element
     * @returns
     */
    toString(element) {
        if (element) {
            if (element instanceof HTMLElement) {
                const cs = element.classList;
                let cns = '';
                for (let index = 0; index < cs.length; index++) {
                    cns += '.' + cs[index];
                }
                const id = element.id;
                return element.tagName.toLocaleLowerCase() + (id ? '#' + id : '') + cns;
            }
            else {
                return element;
            }
        }
        else {
            const array = [];
            for (let i = 0; i < this.length; i++) {
                array.push(this.toString(this[i]));
            }
            return `Flysel(${this.length}) [${array.join(', ')}]`;
        }
    }
    /**
     * 获取相对窗口的位置
     * @returns
     */
    offwin() {
        let d = this[0];
        let l = d.offsetLeft;
        let t = d.offsetTop;
        while (true) {
            // @ts-ignore
            d = d.offsetParent;
            if (!d) {
                l -= window.scrollX;
                t -= window.scrollY;
                return { top: t, left: l };
            }
            l += d.offsetLeft;
            l -= d.scrollLeft;
            t += d.offsetTop;
            t -= d.scrollTop;
        }
    }
    /**
     *
     * @returns 获取相对html顶部的位置
     */
    offset() {
        let d = this[0];
        let l = d.offsetLeft;
        let t = d.offsetTop;
        while (true) {
            // @ts-ignore
            d = d.offsetParent;
            if (!d) {
                return { top: t, left: l };
            }
            l += d.offsetLeft;
            t += d.offsetTop;
        }
    }
    /**收集表单 */
    collect(option) {
        return new FormJson(this, option);
    }
    /**选择方法 */
    /**
     * 从后代中选择
     * @param {string} selector
     * @returns
     */
    find(selector = '*') {
        const fs = new Flysel;
        for (let fi = 0; fi < this.length; fi++) {
            const ns = this[fi].querySelectorAll(selector);
            for (let ni = 0; ni < ns.length; ni++) {
                fs.add(ns[ni]);
            }
        }
        return fs;
    }
    /**
     * 从子代中选择
     * @param {string} selector
     * @returns
     */
    child(selector = '*') {
        selector = ':scope>' + selector;
        const fs = new Flysel;
        for (let fi = 0; fi < this.length; fi++) {
            const ns = this[fi].querySelectorAll(selector);
            for (let ni = 0; ni < ns.length; ni++) {
                fs.add(ns[ni]);
            }
        }
        return fs;
    }
    /**
     * 从前辈元素中选择
     * @param {string} selector
     */
    parent(selector) {
        const fs = new Flysel;
        for (let i = 0; i < this.length; i++) {
            const pe = selector ? this[i].closest(selector) : this[i].parentElement;
            if (pe && !fs.includes(pe))
                fs.add(pe);
        }
        return fs;
    }
    /**
     * 从兄弟元素中选择
     * @param {string} selector
     * @returns
     */
    sibling(selector = '*') {
        const fs = new Flysel;
        for (let fi = 0; fi < this.length; fi++) {
            const e = this[fi];
            const pe = e.parentElement;
            if (!pe)
                continue;
            const es = pe.querySelectorAll(':scope>' + selector);
            for (let ei = 0; ei < es.length; ei++) {
                const b = es[ei];
                if (!e.isEqualNode(b))
                    fs.add(b);
            }
        }
        return fs;
    }
    /**操作类名 */
    /**
     * 添加类名
     * @param {string[]} className
     * @returns
     */
    addClass(...className) {
        for (let i = 0; i < this.length; i++) {
            this[i].classList.add(...className);
        }
        return this;
    }
    /**
     * 删除类名
     * @param {string[]} className
     * @returns
     */
    removeClass(...className) {
        for (let i = 0; i < this.length; i++) {
            this[i].classList.remove(...className);
        }
        return this;
    }
    /**
     * boolean为true则添加类名反之则删除类名
     * @param {Boolean} boolean
     * @param {string[]} className
     * @returns
     */
    booleClass(boolean, ...className) {
        if (boolean) {
            for (let i = 0; i < this.length; i++) {
                this[i].classList.add(...className);
            }
        }
        else {
            for (let i = 0; i < this.length; i++) {
                this[i].classList.remove(...className);
            }
        }
        return this;
    }
    /**
     * 检测是否存在指定类名
     * @param {string} className
     * @returns
     */
    hasClass(className) {
        return this[0].classList.contains(className);
    }
    /**
     * 若存在已类名则删除类名，反之则添加类名
     * @param {string} className
     * @returns
     */
    toggleClass(...className) {
        for (let i = 0; i < this.length; i++) {
            const classLiet = this[i].classList;
            if (classLiet.contains(className[0]))
                classLiet.remove(...className);
            else
                classLiet.add(...className);
        }
        return this;
    }
    /**
     * 活跃类名：添加指定类名并删除所有兄弟元素的指定类名
     * @param {string[]} className
     * @returns
     */
    activeClass(...className) {
        for (let i = 0; i < this.length; i++) {
            const e = this[i];
            const pe = e.parentElement;
            if (!pe)
                continue;
            const es = pe.querySelectorAll(':scope>*');
            for (let ei = 0; ei < es.length; ei++) {
                const b = es[ei];
                if (e.isEqualNode(b))
                    b.classList.add(...className);
                else
                    b.classList.remove(...className);
            }
        }
        return this;
    }
    on(ags1, ags2, ags3) {
        if (typeof ags1 === 'object') {
            for (const key in ags1) {
                // @ts-ignore
                this.on(key, ags1[key], ags2);
            }
        }
        else {
            if (ags1.includes(',')) {
                const ts = ags1.split(/,|, /);
                for (let i = 0; i < ts.length; i++) {
                    // @ts-ignore
                    this.on(ts[i], ags2, ags3);
                }
                return this;
            }
            // @ts-ignore
            hook.emit('on', { flysel: this, type: ags1, listener: ags2, option: ags3 });
            for (let i = 0; i < this.length; i++) {
                const e = this[i];
                // @ts-ignore
                const liser = ags3?.entrust ? (function (event) {
                    // @ts-ignore
                    const e = event.target.closest(ags3.entrust);
                    if (e) {
                        // @ts-ignore
                        ags2.call(new Flysel(e));
                    }
                }) :
                    // @ts-ignorec
                    ags2.bind(new Flysel(e));
                // @ts-ignore
                if (ags2.name) {
                    // @ts-ignore
                    if (e._liserMap) {
                        // @ts-ignore
                        e._liserMap.set(ags2, liser);
                    }
                    else {
                        // @ts-ignore
                        e._liserMap = new Map([[ags2, liser]]);
                    }
                }
                // @ts-ignore
                e.addEventListener(ags1, liser, ags3);
            }
        }
        return this;
    }
    /**
     * 移除事件侦听器
     * @param {string} type
     * @param {FlyselListener} listener
     * @returns
     */
    off(type, listener) {
        for (let i = 0; i < this.length; i++) {
            const e = this[i];
            // @ts-ignore
            const rl = e._liserMap?.get(listener);
            if (rl) {
                // @ts-ignore
                e.removeEventListener(type), e._liserMap.delete(listener);
            }
            else {
                // @ts-ignore
                e.removeEventListener(type, listener);
            }
        }
        return this;
    }
    css(ags1, ags2) {
        if (typeof ags1 === 'object') {
            for (const key in ags1) {
                let value = ags1[key];
                if (typeof value !== 'string' && STYLEDEGREE.has(key))
                    value = value + 'px';
                //@ts-ignore
                this.css(key, value);
            }
            return this;
        }
        else if (ags2 !== undefined) {
            // @ts-ignore
            if (typeof ags2 !== 'string' && STYLEDEGREE.has(ags1))
                ags2 = ags2 + 'px';
            for (let ei = 0; ei < this.length; ei++) {
                this[ei].style[ags1] = ags2;
                this[ei].dispatchEvent(new StyleEvent('stylechange', {
                    style: ags1,
                    value: ags2
                }));
            }
            return this;
        }
        else {
            return this[0].style[ags1];
        }
    }
    upIncludes(selector) {
        for (let i = 0; i < this.length; i++) {
            if (this[i].closest(selector))
                return true;
        }
        return false;
    }
    /**
     * 在元素内添加元素节点或文本
     * @param {...(string | Element)[]} eles
     * @returns
     */
    append(...eles) {
        for (let i = 0; i < this.length; i++) {
            for (let ei = 0; ei < eles.length; ei++) {
                const e = eles[ei];
                if (typeof e === 'string') {
                    this[i].insertAdjacentHTML('beforeend', e);
                }
                else {
                    this[i].insertAdjacentElement('beforeend', e);
                }
            }
        }
        return this;
    }
    /**
     * 在元素内添加HTML
     * @param html
     * @returns
     */
    addHTML(html) {
        for (let i = 0; i < this.length; i++) {
            this[i].insertAdjacentHTML('beforeend', html);
        }
        return this;
    }
    /**
     * 在元素内添加节点
     * @param element
     * @returns
     */
    addElement(element) {
        for (let i = 0; i < this.length; i++) {
            this[i].insertAdjacentElement('beforeend', element);
        }
        return this;
    }
    /**
     * 插入HTML
     * @param where 插入位置
     * @param html
     * @returns
     */
    insertHTML(where, html) {
        for (let i = 0; i < this.length; i++) {
            this[i].insertAdjacentHTML(where, html);
        }
        return this;
    }
    /**
     * 插入Element
     * @param where 插入位置
     * @param Element
     * @returns
     */
    insertElement(where, element) {
        for (let i = 0; i < this.length; i++) {
            this[i].insertAdjacentElement(where, element);
        }
        return this;
    }
    prop(attr, value) {
        if (value) {
            for (let i = 0; i < this.length; i++) {
                // @ts-ignore
                this[i][attr] = value;
            }
            return this;
        }
        else {
            // @ts-ignore
            return this[0][attr];
        }
    }
    attr(attr, value) {
        if (value) {
            for (let i = 0; i < this.length; i++) {
                // @ts-ignore
                this[i].setAttribute(attr, value);
            }
            return this;
        }
        else {
            return this[0].getAttribute(attr);
        }
    }
    /**
     * 获取对象属性为数组
     * @param {string} prop
     * @returns
     */
    getProp(prop) {
        const ar = [];
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            ar.push(this[0][prop]);
        }
        return ar;
    }
    /**
     * 获取内联属性为数组
     * @param {string} attr
     * @returns
     */
    getAttr(attr) {
        const ar = [];
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            ar.push(this[0].getAttribute(attr));
        }
        return ar;
    }
    /**
     * 模板渲染
     * @param data
     * @param option
     */
    template(data, option) {
        if (!this._render)
            this._render = template(this.html, option);
        let hl = this._render(data);
        if (hl.startsWith('<!--'))
            hl = hl.slice(4, -3);
        this.html = hl;
    }
    scrollBy(x, y) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].scrollBy(x, y);
        }
        return this;
    }
    scrollTo(x, y) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].scrollTo(x, y);
        }
        return this;
    }
    /**触发click */
    click() {
        for (let i = 0; i < this.length; i++) {
            this[i].click();
        }
        return this;
    }
    /**触发focus */
    focus() {
        for (let i = 0; i < this.length; i++) {
            this[i].focus();
        }
        return this;
    }
    /**触发blur */
    blur() {
        for (let i = 0; i < this.length; i++) {
            this[i].blur();
        }
        return this;
    }
    /**隐藏元素(display:none) */
    hide() {
        for (let i = 0; i < this.length; i++) {
            this[i].style.display = 'none';
        }
        return this;
    }
    /**显示元素(display:block) */
    block() {
        for (let i = 0; i < this.length; i++) {
            this[i].style.display = 'block';
        }
        return this;
    }
    /**显示元素(display:flex) */
    flex() {
        for (let i = 0; i < this.length; i++) {
            this[i].style.display = 'flex';
        }
        return this;
    }
    /**常用属性代理 */
    /**文本 */
    get text() {
        return this[0].innerText;
    }
    set text(v) {
        for (let i = 0; i < this.length; i++) {
            this[i].innerText = v;
        }
    }
    /**HTML */
    get html() {
        return this[0].innerHTML;
    }
    set html(v) {
        for (let i = 0; i < this.length; i++) {
            this[i].innerHTML = v;
        }
    }
    /**元素宽度，等同于offsetWidth */
    get width() {
        return this[0].offsetWidth;
    }
    set width(v) {
        for (let i = 0; i < this.length; i++) {
            this[i].style.width = v + 'px';
        }
    }
    /**元素宽度，等同于offsetHeight */
    get height() {
        return this[0].offsetHeight;
    }
    set height(v) {
        for (let i = 0; i < this.length; i++) {
            this[i].style.height = v + 'px';
        }
    }
    /**name */
    get name() {
        // @ts-ignore
        return this[0].name;
    }
    set name(v) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].name = v;
        }
    }
    /**id */
    get id() {
        // @ts-ignore
        return this[0].id;
    }
    set id(v) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].id = v;
        }
    }
    /**value */
    get value() {
        // @ts-ignore
        let v = this[0].value;
        if (this[0].hasAttribute('number'))
            v = !v;
        return v;
    }
    set value(v) {
        for (let i = 0; i < this.length; i++) {
            //@ts-ignore
            if (this[i].value !== v) {
                // @ts-ignore
                this[i].value = v;
                this[i].dispatchEvent(new InputEvent('input', {
                    data: v,
                    bubbles: true,
                    cancelable: true
                }));
            }
        }
    }
    /**type */
    get type() {
        // @ts-ignore
        return this[0].type;
    }
    set type(v) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].type = v;
        }
    }
    /**checked */
    get checked() {
        // @ts-ignore
        return this[0].checked;
    }
    set checked(v) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].checked = v;
        }
    }
    /**checked */
    get src() {
        // @ts-ignore
        return this[0].src;
    }
    set src(v) {
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].src = v;
        }
    }
    /**left */
    get left() {
        // @ts-ignore
        return this[0].offsetLeft;
    }
    set left(v) {
        // @ts-ignore
        if (typeof v === 'number')
            v += 'px';
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].style.left = v;
        }
    }
    /**top */
    get top() {
        // @ts-ignore
        return this[0].offsetTop;
    }
    set top(v) {
        // @ts-ignore
        if (typeof v === 'number')
            v += 'px';
        for (let i = 0; i < this.length; i++) {
            // @ts-ignore
            this[i].style.top = v;
        }
    }
    /**只读属性 */
    get clientWidth() {
        // @ts-ignore
        return this[0].clientWidth;
    }
    get clientHeight() {
        // @ts-ignore
        return this[0].scrollHeight;
    }
    get scrollWidth() {
        // @ts-ignore
        return this[0].scrollWidth;
    }
    get scrollHeight() {
        // @ts-ignore
        return this[0].scrollHeight;
    }
    get scrollLeft() {
        // @ts-ignore
        return this[0].scrollLeft;
    }
    get scrollTop() {
        // @ts-ignore
        return this[0].scrollTop;
    }
    /**静态方法 */
    /**
     * 从类数组对象生成实例
     * @param {ClassArray} array 类数组对象
     * @returns
     */
    static from(array) {
        const fs = new Flysel;
        for (let index = 0; index < array.length; index++) {
            fs.add(array[index]);
        }
        return fs;
    }
}
/**
 * flying select
 * @param selector
 * @returns
 */
export const flysel = function (selector = '*', context = document) {
    if (typeof selector === 'string') {
        // @ts-ignore
        return Flysel.from(context.querySelectorAll ? context.querySelectorAll(selector) : context.find(selector));
    }
    else if (selector instanceof HTMLElement) {
        return new Flysel(selector);
    }
    else if (selector.length) {
        return Flysel.from(selector);
    }
    return new Flysel;
};
// @ts-ignore
Flysel.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
// @ts-ignore
Flysel.prototype[Symbol.toStringTag] = 'Flysel';
// @ts-ignore
flysel.document = new Flysel(document);
flysel.body = new Flysel(document.body);
flysel.html = new Flysel(document.documentElement);
// @ts-ignore
flysel.on = Flysel.prototype.on.bind(flysel.document);
// @ts-ignore
flysel.off = Flysel.prototype.off.bind(flysel.document);
export default flysel;
const forR = /^\{\{for.*?\(.*?\)\}\}$/, forRe = /^\{\{for\}\}$/, insR = /\{\{[\s\S]*?\}\}/g, braR = /\(.*?\)/;
const presetStr = `eval(\`var {\${Object.keys(data).join(',')}}=data\`);`;
/**
 * 解析模板
 * @param {string} tem
 * @param {*} option
 */
export function template(tem, option) {
    let str = tem.trim()
        .replace(insR, s => {
        if (forR.test(s)) {
            const si = s.indexOf('(');
            const ei = s.indexOf(')', si);
            return `\${${s.slice(5, si).trim() || 'data'}.map((${s.slice(si + 1, ei)})=>\``;
        }
        if (forRe.test(s))
            return '`).join(\'\')}';
        return '${' + s.slice(2, -2) + '}';
    });
    str = 'return `' + str + '`';
    if (option) {
        if (option.preset) {
            str = presetStr + str;
        }
    }
    const render = new Function(...Object.keys(builtMethods), 'data', str);
    return render.bind(null, ...Object.values(builtMethods));
}
/**模板引擎内置方法 */
const builtMethods = {
    interval(index, ...int) {
        return int[index % int.length];
    }
};
const syncPlugin = {
    object(sync, prom) {
        sync.on('change', function (e) {
        });
    },
    form(sync, prom) {
        let el, option;
        if (typeof prom === 'string') {
            el = flysel(prom);
        }
        else if (prom instanceof Flysel) {
            el = prom;
        }
        else {
            el = typeof prom.el === 'string' ? flysel(prom.el) : prom.el;
            option = prom.option;
        }
        // 初始化form数据
        const json = new FormJson(el, option);
        Object.assign(sync.proxy, json);
        // form同步到sync
        el.on('input', (eve) => {
            const ele = eve.target;
            const name = ele.name;
            const value = ele.value;
            if (name && ele) {
                if (ele.type === 'radio') {
                    if (ele.checked) {
                        sync.set(name, value);
                    }
                }
                else if (ele.type === 'checkbox') {
                    sync.item(name, value, ele.checked);
                }
                else {
                    sync.set(name, value);
                }
            }
        });
        // sync同步到form
        sync.on('set', e => {
            const fe = el.find(`[name="${e.key}"]`);
            for (let i = 0; i < fe.length; i++) {
                const ele = fe[i];
                const t = ele.type;
                if (t === 'checkbox')
                    throw new FlyselError('SyncPlugin[form]:"set"事件不能同步到[type="checkbox"]元素');
                if (ele.type === 'radio') {
                    if (ele.value === e.value?.toString()) {
                        ele.checked = true;
                    }
                }
                else {
                    ele.value = e.value?.toString() || '';
                }
            }
        });
        sync.on('item', e => {
            const fe = el.find(`input[name="${e.key}"][value="${e.item}"]`);
            for (let i = 0; i < fe.length; i++) {
                const ele = fe[i];
                const t = ele.type;
                if (t !== 'checkbox')
                    throw new FlyselError(`SyncPlugin[form]:"item"事件不能同步到[type="${t}"]元素`);
                ele.checked = !!e.add;
            }
        });
    },
    style(sync, prom) {
        prom.on('stylechange', (eve) => {
            const ele = eve.target;
            const name = ele.getAttribute('name');
            if (name) {
                sync.set(name, ele.getAttribute('style') || '');
            }
        });
        sync.on('set', e => {
            for (let i = 0; i < prom.length; i++) {
                if (prom[i].getAttribute('name') === e.key)
                    prom[i].setAttribute('style', e.value?.toString() || '');
            }
        });
    },
    change(sync, prom) {
        sync.on('change', prom);
    }
};
/**数据同步 */
export class Sync extends FlyselEvent {
    src;
    proxy;
    constructor(src, option = {}) {
        super();
        this.src = src;
        //代理对象
        this.proxy = new Proxy(src, {
            get: (o, p) => {
                const v = o[p];
                if (v instanceof Set)
                    return new SetSync(v, this, p);
                return v;
            },
            set: (o, p, v) => {
                this.set(p, v);
                return true;
            }
        });
        // 运行同步插件
        const ks = Object.keys(option);
        for (let i = 0; i < ks.length; i++) {
            const k = ks[i];
            const v = option[k];
            syncPlugin[k](this, v);
        }
    }
    set(key, value) {
        const t = typeof value;
        if (t !== 'string' && t !== 'number' && t !== 'undefined' && !(value instanceof Set))
            throw new FlyselError('不受支持的数据类型[' + t + '],仅支持[string][number][undefined][Set]');
        const { src } = this;
        if (src[key] === value)
            return false;
        //@ts-ignore
        src[key] = value;
        this.emit('change', { key, value });
        this.emit('set', { key, value });
        return true;
    }
    item(key, item, add) {
        const t = typeof item;
        if (t !== 'string' && t !== 'number' && t !== 'undefined')
            throw new FlyselError('不受支持的数据类型[' + t + '],仅支持[string][number][undefined]');
        if (add) {
            this.add(key, item);
        }
        else {
            this.del(key, item);
        }
        this.emit('change', { key, value: this.src[key], add });
        this.emit('item', { key, item, add });
    }
    add(key, item) {
        const { src } = this;
        const set = src[key];
        if (set instanceof Set) {
            set.add(item);
        }
        else {
            //@ts-ignore
            src[key] = new Set([item]);
        }
        this.emit('add', { key, item });
    }
    del(key, item) {
        const { src } = this;
        const set = src[key];
        if (set instanceof Set) {
            set.delete(item);
        }
        else {
            //@ts-ignore
            src[key] = new Set();
        }
        this.emit('del', { key, item });
    }
    toJSON() {
        const obj = {};
        const ks = Object.keys(this.src);
        for (let i = 0; i < ks.length; i++) {
            const k = ks[i];
            const v = this.src[k];
            if (v instanceof Set) {
                obj[k] = Array.from(v);
            }
            else {
                const t = typeof v;
                if (t === 'string' || t === "number") {
                    obj[k] = v;
                }
                else if (v.toString) {
                    obj[k] = v.toString();
                }
            }
        }
        return obj;
    }
}
/**Set同步 */
export class SetSync {
    #src;
    #sync;
    #key;
    constructor(src = new Set, sync, key) {
        this.#src = src;
        this.#sync = sync;
        this.#key = key;
    }
    get size() {
        return this.#src.size;
    }
    has(v) {
        return this.#src.has(v);
    }
    clear() {
        return this.#src.clear();
    }
    add(value) {
        if (!this.#src.has(value)) {
            this.#sync.item(this.#key, value, true);
            this.#src.add(value);
        }
        return this;
    }
    delete(value) {
        if (this.#src.has(value)) {
            this.#sync.item(this.#key, value);
            this.#src.delete(value);
        }
        return false;
    }
    entries() {
        return this.#src.entries();
    }
    forEach(callBack) {
        return this.#src.forEach(callBack);
    }
    del(value) {
        return this.delete(value);
    }
}
/**
 * 数据同步
 * @param option 配置
 * @returns
 */
export function sync(src, option = {}) {
    const sync = new Sync(src, option);
    return sync.proxy;
}
// 自定义事件：mousepressmove
{
    let e;
    flysel.document.on({
        mousedown(ev) {
            e = ev.target;
        },
        mousemove(ev) {
            e?.dispatchEvent(new MouseEvent('mousepressmove', ev));
        },
        mouseup() {
            e = null;
        }
    });
}
